%% pilot experiment for adapted saliency paradigm
%participant setup

subject= ['S',input('What is the subject number?', "s")]; % check in table which number
day = input('Is this the 1st or 2nd testing session for this participant? (1/2)', 's');
modality = input('Which modality will be tested today? (VAS/EEG)','s');
filename=[subject, '_day',day, '_',modality,'_' datestr(now,'dd-mmmm-yyyy')];

if day=='2'
    F= sprintf('%s*.mat',subject);
    file= dir(F);
    load(file.name,'stim_temp', 'trial_order'); %loads individual stim temperatur and randomization from 1st session
end

%% TCS initialization
%%%%%%%%%%%%%%%%%
com = 'COM4';        % Change it to the correct port
tcs2.init_serial(com);
tcs2.init_tcs;
tcs2.verbose(1);    % 1: no messages | 2: information messages

disp('TCS initialized.')
%%%%%%%%%%%%%%%%%

%% NI initialization
%%%%%%%%%%%%%%%%%
input_channels = 0;
output_channels = [0 1 2];
NI = NIdaq.init_analog(input_channels, output_channels, 100); % Opens channels for VAS recording, TCS trigger, and EEG trigger)
% TCS should be triggered from the second row and EEG from the third
%%%%%%%%%%%%%%%%%

NIdaq.add_listener(NI);
if strcmp(modality,'VAS')
    NI.IsContinuous = true;
end
disp('NI initialized')

%% VAS set up
if strcmp(modality,'VAS')
    vas_init_done = false;
    while ~vas_init_done
        waitfor(msgbox('Put the VAS to min and max in any order after pressing OK (5 seconds)'));
        NI.queueOutputData([5*ones(5*NI.Rate-1,3); zeros(1,3)]);
        NI.NotifyWhenDataAvailableExceeds=5*NI.Rate;
        NI.startBackground;
        pause(6);
        E = NIdaq.get_data;
        %%%%%%%%%%%%%%%%%
        mini = min(E);
        maxi = max(E)-mini;
        answer0 = questdlg(['VAS has returned these values: '  sprintf('\n') 'Maximum: ' num2str(maxi) sprintf('\n') 'Minimum: ' num2str(mini) sprintf('\n') 'Are these OK?']);
        if strcmp(answer0, 'Yes')
            vas_init_done = true;
        end
    end
end
disp('VAS initialized')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Variable setup 

%%% Stim Temp (without staircase)
    base_temp = 35;
  
%%% Frequencies and Durations
    oddball_frequency = 1/8 ;                                               % Frequency of the salient stimuli (in Hz). Must be a multiple of 0.2Hz.
    oddball_appearance = 4 ;                                                % Every Xth stimulus will be replaced by an oddball.
    oddball_amount = 10 ;                                                   % Number of oddballs required for the frequency-tagging to be relevant.
    stimulus_duration = 1/(oddball_frequency*oddball_appearance) ;          % Length of a stimulus (in s).
    trial_duration = oddball_amount*oddball_appearance*stimulus_duration ;  % Total duration of a trial.
    number_of_stimulus = trial_duration/stimulus_duration;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    num_of_warmup_trials = 1;
    trials = {'lowOddball' 'highOddball'};
    trial_rep = 2;
    trials_per_block = length(trials)*trial_rep;
    num_of_blocks = 6;

if day == '1'   

     % Staircase
    staircase_number_of_stimulus = round(number_of_stimulus/2);
    staircase_trial_duration = staircase_number_of_stimulus*stimulus_duration;
    max_temp = 51;
    min_temp = 48;
    start_temp = 49;
    low_increment = 0.5;
    high_increment = 2*low_increment;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      % Trials
    rng('shuffle');
     %trials = {'lowOddball' 'highOddball'};
     %trial_rep = 2;
     %trials_per_block = length(trials)*trial_rep;
     %num_of_blocks = 3;
    trial_order = cell(num_of_blocks,trials_per_block);
    
    for a=1:num_of_blocks
        temporary = repmat(1:length(trials),1,trial_rep);
        temporary = temporary(randperm(length(temporary)));
        trial_order(a,:)=trials(temporary);
    end
    trial_order = Shuffle(trial_order,2);   %shuffles order of conditions for each row
    clear temporary;
    % Rows are blocks
    % Columns are trials
    num_of_trials = size(trial_order,1)*size(trial_order,2);
    num_of_warmup_trials = 1;
end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    pause_between_trials = 10; % in seconds
    pause_between_blocks = 120;     % in seconds
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    bins= NI.Rate*(trial_duration+3); % add 3 extra seconds of recording
    voltage_matrix = repmat(flip((0:(bins-1))*5/bins),3,1)';

disp('variables initialized')
%% TCS commands
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tcs2.write_serial('Ue11111');   % allows for custom profiles
tcs2.write_serial('Ose');       % allows for triggering through the NI
tcs2.set_neutral_temperature(base_temp);
%%%%%%%%%%%%%%%%

disp('TCS commands initialized')
%% TCS check 
% tcs2.enable_temperature_feedback(100);
% temporary = tcs2.read_serial ;              % Flush data that might still be there
% number_of_stimulation=1; % Change this to your number of stimulations
% temperature_feedback=cell(number_of_stimulation,5); % Temperature data will be stored here.
% TCS_Check_CP = profiles.sine_wave(base_temp, start_temp, stimulus_duration, number_of_stimulus);
% tcs2.write_serial_slow(TCS_Check_CP);
% waitfor(msgbox('Press OK to start mock stimulation to check the TCS is functionning (80s).'));
% tcs2.stimulate;
% pause(trial_duration+5);
% beep;
% disp('Extracting temperature feedback...')  % Optional
% temporary = tcs2.read_serial ;              % Extract raw data from TCS
% temporary_index = strfind(temporary,'+');   % Extract position of temperature data from raw data
% temp_feed=zeros(1,length(temporary_index)); % Preallocation for speed purposes
% %%%%%%%%%%%%%%%%
% Extract and store temperature data in a cell array
% for a=1:length(temporary_index)
%    temp_feed(a)=str2double(temporary(temporary_index(a)+1:temporary_index(a)+4));
% end
% stimulation_number = 1;           
% for b=1:5
%    temperature_feedback{stimulation_number,b}=temp_feed(b:5:end); 
% end
% color_plot = {'k','b','r','g','m'}; 
%     Colors of the lines in the graphs.
% xvalues=(1:length(temperature_feedback{1}))*10; 
%     Recording at 100Hz, so *10 makes it milliseconds
% hold on
% for c=1:5
%    plot(xvalues,temperature_feedback{stimulation_number,c},color_plot{c})
%         makes the graph for a singular stimulation.
% end
% hold off
% title(['Temperature Curve of Each Area for Stimulation n�' int2str(stimulation_number)]);
% legend('1','2','3','4','5');
% xlabel('Time (ms)');
% ylabel('Temperature (�C)');
% ---------------
% The following two lines pause the script and make it so pressing enter
% closes the graph and unpauses the script.
% waitfor(msgbox('Press OK to continue.'));
% close;
% clear temporary
% tcs2.disable_temperature_feedback;

%% Pre-allocation (only for VAS modality)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if strcmp(modality,'VAS')
    redo = {};
    D = zeros(bins, num_of_trials); % For raw VAS data
    data_table = array2table(zeros(bins,num_of_trials)); % For processed VAS data
    variable_names = cell(1,num_of_trials);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    for a = 1:num_of_blocks
        for b = 1:trials_per_block
            variable_names{((a-1)*trials_per_block+b)}=['Block' int2str(a) '_Trial' int2str(b) '_' trial_order{a,b}];
        end
    end
    data_table.Properties.VariableNames = variable_names;
end

disp('VAS allocated')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Staircase (only for day 1)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if day == '1'
    done = false;
    going_down = false;
    stim_temp = start_temp;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    while ~done
        CP_staircase = profiles.sine_wave(base_temp, stim_temp, stimulus_duration, staircase_number_of_stimulus);
        tcs2.write_serial_slow(CP_staircase);
        pause(pause_between_trials);
        msg = ['Current stimulation temperature: ' sprintf('%g',stim_temp) '�C' sprintf('\n') 'Press OK to start stimulating for ' int2str(staircase_trial_duration) ' seconds.'];
        waitfor(msgbox(msg,'Staircase'));
        tcs2.stimulate;
        pause(staircase_trial_duration);
        beep;
        pain_any = questdlg('Was it painful at ANY TIME during the stimulation ?');
        switch pain_any
            case 'No'                    
                stim_temp = stim_temp + high_increment;
                going_down = false;
            case 'Yes'
                pain_end = questdlg('Was it painful in the SECOND HALF of the trial ?');
                switch pain_end
                    case 'No'            
                        stim_temp = stim_temp + low_increment;
                        if going_down
                            done = true;
                        end
                    case 'Yes'            
                        stim_temp = stim_temp - low_increment;
                        going_down = true;
                end
        end
        if stim_temp > max_temp
            stim_temp=max_temp;
            done = true;
            waitfor(msgbox('Maximum temperature reached. End of staircase.'));
        elseif stim_temp < min_temp
            stim_temp = min_temp;
            done = true;
            waitfor(msgbox('Minimum temperature reached. End of staircase.'));
        end
    end
    waitfor(msgbox(['Chosen stimulation temperature: ' sprintf('%g',stim_temp) '�C'],'Staircase'));
end
%% Custom Profiles
% Saliency Variations
warmup_temp = 44;
lowOddball_temp  = stim_temp-2;
highOddball_temp = stim_temp+2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
lowOddball_CP = profiles.sine_wave_temp_oddball(base_temp, stim_temp,lowOddball_temp,stimulus_duration, number_of_stimulus, oddball_appearance);
highOddball_CP = profiles.sine_wave_temp_oddball(base_temp, stim_temp,highOddball_temp,stimulus_duration, number_of_stimulus, oddball_appearance);
Warmup_CP = profiles.sine_wave(base_temp,warmup_temp,stimulus_duration, number_of_stimulus);

disp('Custom profiles are updated')
%% Warm Up Trial
tcs2.write_serial_slow(Warmup_CP);
switch modality
    case 'VAS'
        waitfor(msgbox('The following trial(s) will allow the participant to train with the use of the VAS.'));
    case 'EEG'
        waitfor(msgbox('The following trial(s) will allow the participant to train their behaviour for the EEG.'));
end
for a=1:num_of_warmup_trials
    waitfor(msgbox(['Warm-up trial ' int2str(a) sprintf('\n') 'Press Any Key to Start Stimulating for ' int2str(trial_duration) ' Seconds'], 'Warm-Up')) ;
    tcs2.stimulate;
    pause(trial_duration);
    beep;
    pause(pause_between_trials);
end
%% Experiment Loop
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for a=1:num_of_blocks
    for b=1:trials_per_block
        switch trial_order{a,b}
            case 'lowOddball'
                tcs2.write_serial_slow(lowOddball_CP);
            case 'highOddball'
                tcs2.write_serial_slow(highOddball_CP);
        end
        waitfor(msgbox(['Block ' int2str(a) ' out of ' int2str(num_of_blocks) ...
            sprintf('\n') 'Stimulation ' int2str(b) ' out of ' int2str(trials_per_block) ...
            sprintf('\n') 'Press OK to start stimulation.']));
        NI.queueOutputData(voltage_matrix);
        NI.NotifyWhenDataAvailableExceeds=bins;
        NI.startBackground;
        disp('stimulating...')
        pause(trial_duration);
        beep;
       if strcmp(modality,'VAS')
           pause(4); % 3s for finishing the stimulation, 1s to make sure NI is ready to send
           index = (a-1)*trials_per_block+b;
           D(:,index) = NIdaq.get_data;
           % redo trials?
           plot(D(:,index))
           answer = questdlg('Did the VAS work correctly ?');
           if strcmp(answer,'No')
               redo{end+1} = trial_order{a,b};
           end
       end
       if ~(b==trials_per_block)
           if strcmp(modality,'VAS')
               pause(pause_between_trials-4); % to compensate for the required 4s pause in the VAS condition.
           else
               pause(pause_between_trials)
           end
       end
       if strcmp(modality,'VAS')
        VAS_Results(:,index) = 10/ maxi * D(:,index);
        data_table(:,index) = array2table(VAS_Results(:,index));
        save(filename);
        disp('Data saved.');
       end
    end

    if a==num_of_blocks
        switch day
            case '1'
                msgbox(['First part of the experiment is completed.' ...
                    sprintf('\n') 'See you in a week!'])
            case '2'
                msgbox(['Experiment completed.' ...
                    sprintf('\n') 'Don''t forget to sign th remuneration form!']);
        end
    else
        disp(['Block ' int2str(a) ' out of ' int2str(num_of_blocks) ' completed.' ...
            sprintf('\n') 'Take a small break.']);
        pause(pause_between_blocks);
    end
end